#!/usr/bin/php
<?php
/*  ================================================================== *\
    (C) Copyright 2009 by Kenneth Downs, Donald Organ, Justin Dearing

    This file is part of Triangulum.

\*  ================================================================== */

/**
 * Execute the processing unit tests
 * 
 * This is the comprehensive test management program for all
 * process tests.  Process tests ensure that spec files
 * are processed correctly.  
 * 
 * This program expects the "tests-process" directory to be
 * in a subdirectory just below this actual program. 
 * 
 * See the wiki for more information
 *
 * @package Andromeda
 * @author Ken Downs <kdowns@downsfam.net>
 */

main();

/**
 * 
 * @return unknown_type
 */
function main() {
    $dirs = scandir("./tests-process/");
    $prefix = '000.0';
    $pass   = 0;
    $failed = 0;
    $notest = 0;
    
    # KFD 1/29/11 a running tally of errors that are trapped for
    $errorsMeta = array();
    
    foreach($dirs as $idx=>$dir) {
        if(substr($dir,0,1)=='.') continue;
        # KFD 1/2/10 Necessary if a bogus run creates these dirs
        if($dir=='out') continue;
        if($dir=='debug') continue;
        if($dir=='metaErrors.txt') continue;
        
        if(substr($dir,0,5)<>$prefix) {
            echo "\n\n";
        }
        $prefix = substr($dir,0,5);
        
        // If file does not end in .yaml then its a folder
        if ( substr( $dir, -5 ) !== '.yaml' ) {
            $yamlfile = $dir .'/' .$dir .'.dd.yaml';   
        } else { // otherwise its a YAML file
            $yamlfile = $dir;
        }
        
        # KFD, ensure test is fair by wiping out previous output
        $debugFiles = scandir("./tests-process/$dir/debug");
        foreach($debugFiles as $debugFile) {
            if(!is_dir("./tests-process/$dir/debug/$debugFile")) {
                unlink("./tests-process/$dir/debug/$debugFile");
            }
        }
        
        # KFD 1/29/11 Before running test, see if there is a script
        #             to run
        if(file_exists("./tests-process/$dir/scriptBefore.php"))
            include("./tests-process/$dir/scriptBefore.php");
        
        
        # DO 01-02-2011   Tester needs to pass YAML
        #                 file to triBuild.php using argument system
        $cmd = 'php triBuild.php --yaml=tests-process/' .$yamlfile;
        # Run the test
        `$cmd`;
        # Get the description
        $desc = file_get_contents("tests-process/$dir/desc.txt");
        while(substr($desc,-1)=="\n") {
            $desc = substr($desc,0,strlen($desc)-1);
        }
        
        # KFD 1/29/11 After running test, see if there is a script
        #             to run
        if(file_exists("./tests-process/$dir/scriptAfter.php"))
            include("./tests-process/$dir/scriptAfter.php");
        
        
        # For making things line up
        $xdir = str_pad($dir,25);

        # Now read the files we are supposed to check, get
        # rid of '.' and '..'
        if(!is_dir("tests-process/$dir/compare")) {
            echo "\n----   $xdir $desc";
            echo "\n  --   the compare/ subdirectory does not exist";
            $notest++;
            continue;
        }
        $files = scandir("tests-process/$dir/compare");
        if(!is_array($files)) {
            echo "\n----   $xdir $desc";
            echo "\n  --   there are no files in the compare/ subdirectory";
            $notest++;
            continue;
        }
        array_shift($files);
        array_shift($files);
        foreach($files as $idx=>$file) {
            if(substr($file,-1)=='~') unset($files[$idx]);
        }
        if(count($files)==0) {
            echo "\n----   $xdir $desc";
            echo "\n  --   there are no files in the compare/ subdirectory";
            $notest++;
            continue;
        }
        
        # KFD 1/29/11 Tally up which errors are being processed
        if(file_exists("tests-process/$dir/debug/errorsMeta.serialize")) {
            $metaE2 = unserialize(
                file_get_contents("tests-process/$dir/debug/errorsMeta.serialize")
            );
            foreach($metaE2 as $region=>$errors) {
                if(!isset($metaErrors[$region])) $metaErrors[$region]=array();
                foreach($errors as $code=>$mdesc) {
                    if(!isset($metaErrors[$region][$code])) {
                        $metaErrors[$region][$code] = array(
                            'desc'=>$mdesc
                           ,'count'=>0
                        );
                    }
                    $metaErrors[$region][$code]['count']++;
                }
            }
        }
        
        # Initialize an empty list of failures and do the comparisons
        $fail = array();
        foreach($files as $file) {
            # KFD 5/14/09 general cleanup
            if(substr($file,0,1)=='.') continue;
            $compare = file_get_contents("tests-process/$dir/compare/$file");
            $debug   = file_get_contents("tests-process/$dir/debug/$file");
            
            if($compare<>$debug) {
                $fail[] = $file;
            }
        }
        
        if(count($fail)==0) {
            $pass++;
            echo "\nPASS   $xdir $desc";
            makeWiki($dir);
        }
        else {
            $failed++;
            echo "\nFAIL** $xdir $desc\n";
            echo "\n  Files that failed:";
            foreach($fail as $onefail) {
                echo "\n    - $onefail";
            }
            echo "\n";
        }
    } 
    
    # Write out the meta-errors
    ob_start();
    var_dump($metaErrors);
    file_put_contents('tests-process/metaErrors.txt',ob_get_clean());
    
    
    echo "\n\n";
    $pf = intval($pass) + intval($failed) + intval($notest);
    echo "\nPassed : ".str_pad(number_format($pass   ,0),6,' ',STR_PAD_LEFT);
    echo "\nNo Test: ".str_pad(number_format($notest ,0),6,' ',STR_PAD_LEFT);
    echo "\nFailed : ".str_pad(number_format($failed ,0),6,' ',STR_PAD_LEFT);
    echo "\nTOTAL  : ".str_pad(number_format($pf     ,0),6,' ',STR_PAD_LEFT);
    echo "\n\n";
}

function makeWiki($dir) {
    $string = "== Summary ==\n\n";
    $string.= file_get_contents("tests-process/$dir/desc.txt");
    $string.= "\n\n";
    $string.= "== Purpose ==\n\n";
    $string.= file_get_contents("tests-process/$dir/desc.wiki");
    $string.= "\n\n";
    $string.= "== Input Dictionary ==\n\n";
    $files  = scandir("./tests-process/$dir/");
    foreach($files as $file) {
       if(substr($file,-8)=='.dd.yaml') {
            $string.="=== $file ===\n\n";
            $string.="{{{\n"
                .file_get_contents("tests-process/$dir/$file")
                ."\n}}}\n\n";
       }
    }
    /*
    if(!file_exists("tests-process/$dir/$dir.dd.yaml")) {
        $string.="--none--\n\n";
    }
    else {
        $string.="{{{\n"
            .file_get_contents("tests-process/$dir/$dir.dd.yaml")
            ."\n}}}\n\n";
    }
    */
    $string.= "== Expected Outputs ==\n\n";
    $files  = scandir("./tests-process/$dir/compare/");
    foreach($files as $file) {
        if(is_dir("tests-process/$dir/$file")) continue;
        
        $string.="=== $file ===\n\n";
        $string.="{{{\n"
            .file_get_contents("tests-process/$dir/compare/$file")
            ."\n}}}\n\n";
    }
    if(!is_dir("./tests-process/$dir/out")) mkdir("./tests-process/$dir/out/");
    file_put_contents("tests-process/$dir/out/$dir.wiki",$string);
}
?>
